from flask import Blueprint, request, jsonify
from src.models.models import db, Subscription, DownloadTask, CrawlLog, SystemConfig
from datetime import datetime
import json
from src.services.remote_folder import calculate_remote_folder_id

# type: ignore

subscriptions_bp = Blueprint('subscriptions', __name__)


@subscriptions_bp.route('/subscriptions', methods=['GET'])
def get_subscriptions():
    """分页获取订阅列表"""
    try:
        # 获取分页参数
        page = int(request.args.get('page', 1))
        page_size = int(request.args.get('page_size', 10))
        query = Subscription.query.order_by(Subscription.created_at.desc())
        total = query.count()
        subscriptions = query.offset((page-1)*page_size).limit(page_size).all()
        return jsonify({
            'success': True,
            'data': [sub.to_dict() for sub in subscriptions],
            'pagination': {
                'page': page,
                'page_size': page_size,
                'total': total
            }
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'message': str(e)
        }), 500


def validate_url_and_site(url, site):
    from urllib.parse import urlparse
    domain_map = {'dygod': 'dygod.net', 'meijutt': 'meijutt.tv'}
    hostname = urlparse(url).hostname or ''
    url_domain = '.'.join(hostname.split('.')[-2:]) if hostname else ''
    site_domain = domain_map.get(site)
    if not site_domain or url_domain != site_domain:
        return False
    return True


@subscriptions_bp.route('/subscriptions', methods=['POST'])
def create_subscription():
    """创建新订阅"""
    try:
        data = request.get_json()
        required_fields = ['name', 'url', 'type', 'site']
        for field in required_fields:
            if not data.get(field):
                return jsonify({
                    'success': False,
                    'message': f'缺少必需字段: {field}'
                }), 400
        # 使用统一校验函数
        if not validate_url_and_site(data['url'], data['site']):
            return jsonify({
                'success': False,
                'message': '订阅地址根域名与订阅网站不一致，请检查！'
            }), 400

        # 检查URL是否已存在
        existing = Subscription.query.filter_by(url=data['url']).first()
        if existing:
            return jsonify({
                'success': False,
                'message': '该订阅地址已存在'
            }), 400

        new_download_directory = data.get('download_directory', '')
        calculated_parent_folder_id = None

        # --- 新增逻辑：在创建订阅前，先尝试获取远程文件夹ID ---
        if new_download_directory:  # 只有当下载目录不为空时才尝试获取
            calculated_parent_folder_id = calculate_remote_folder_id(new_download_directory)
            if calculated_parent_folder_id is None:
                # 如果获取远程文件夹ID失败，则直接返回错误，不创建订阅
                return jsonify({
                    'success': False,
                    'message': '获取远程文件夹ID失败！'
                }), 400  # 使用 400 Bad Request 表示客户端请求的问题

        # --- 新增逻辑：根据全局自动下载设置决定新订阅的自动下载状态 ---
        global_auto_download = SystemConfig.get_config('global_auto_download', 'false') == 'true'
        auto_download_status = global_auto_download  # 新订阅的自动下载状态跟随全局设置

        # 创建新订阅，并将计算出的 parent_folder_id 赋值，同时设置自动下载状态
        subscription = Subscription(
            name=data['name'],
            url=data['url'],
            type=data['type'],
            site=data['site'],  # 新增site字段
            download_directory=new_download_directory,
            parent_folder_id=calculated_parent_folder_id,  # <-- 赋值计算出的ID
            auto_download=auto_download_status  # <-- 根据全局设置设置自动下载状态
        )

        db.session.add(subscription)
        db.session.commit()  # 提交所有更改

        return jsonify({
            'success': True,
            'data': subscription.to_dict(),
            'message': '订阅添加成功'
        })

    except Exception as e:
        db.session.rollback()  # 发生异常时回滚
        return jsonify({
            'success': False,
            'message': str(e)
        }), 500


@subscriptions_bp.route('/subscriptions/<int:subscription_id>', methods=['PUT'])
def update_subscription(subscription_id):
    """更新订阅"""
    try:
        subscription = Subscription.query.get(subscription_id)
        if not subscription:
            return jsonify({
                'success': False,
                'message': '订阅不存在'
            }), 404
        data = request.get_json()
        # 只要site字段存在就校验
        if 'site' in data:
            if not validate_url_and_site(data.get('url', subscription.url), data['site']):
                return jsonify({
                    'success': False,
                    'message': '订阅地址根域名与订阅网站不一致，请检查！'
                }), 400
            subscription.site = data['site']

        # 记录原始值，用于比较和潜在的回滚
        original_download_directory = subscription.download_directory

        # 临时更新订阅对象在内存中的属性，但不提交到数据库
        # 这样可以在计算 parent_folder_id 失败时，回滚所有这些内存中的更改
        if 'name' in data:
            subscription.name = data['name']
        if 'url' in data:
            # 检查新URL是否与其他订阅冲突
            existing = Subscription.query.filter(
                Subscription.url == data['url'],
                Subscription.id != subscription_id
            ).first()
            if existing:
                return jsonify({
                    'success': False,
                    'message': '该订阅地址已被其他订阅使用'
                }), 400
            subscription.url = data['url']
        if 'type' in data:
            subscription.type = data['type']

        new_download_directory = data.get('download_directory', original_download_directory)

        calculated_parent_folder_id = subscription.parent_folder_id  # 默认保持不变

        # --- 新增逻辑：如果下载目录有变化，重新获取 parent_folder_id ---
        if new_download_directory != original_download_directory:
            subscription.download_directory = new_download_directory  # 先更新内存中的目录，用于计算
            if new_download_directory:  # 如果新目录不为空
                calculated_parent_folder_id = calculate_remote_folder_id(new_download_directory)
                if calculated_parent_folder_id is None:
                    # 如果获取远程文件夹ID失败，则回滚所有内存中的更改，并返回错误
                    db.session.rollback()  # 回滚当前会话中的所有更改
                    return jsonify({
                        'success': False,
                        'message': '获取远程文件夹ID失败！'
                    }), 400
            else:  # 如果新目录为空，则 parent_folder_id 也应为空
                calculated_parent_folder_id = None
        # --- 结束新增逻辑 ---

        # 赋值最终确定的 parent_folder_id
        subscription.parent_folder_id = calculated_parent_folder_id

        db.session.commit()  # 提交所有更改，包括 name, url, type, download_directory, parent_folder_id

        return jsonify({
            'success': True,
            'data': subscription.to_dict(),
            'message': '订阅更新成功'
        })

    except Exception as e:
        db.session.rollback()  # 发生异常时回滚
        return jsonify({
            'success': False,
            'message': str(e)
        }), 500


@subscriptions_bp.route('/subscriptions/<int:subscription_id>', methods=['DELETE'])
def delete_subscription(subscription_id):
    """删除订阅"""
    try:
        subscription = Subscription.query.get(subscription_id)
        if not subscription:
            return jsonify({
                'success': False,
                'message': '订阅不存在'
            }), 404

        # 检查是否处于激活状态
        if subscription.is_active:
            return jsonify({
                'success': False,
                'message': '请先关闭订阅状态再删除'
            }), 400

        db.session.delete(subscription)
        db.session.commit()

        return jsonify({
            'success': True,
            'message': '订阅删除成功'
        })

    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': str(e)
        }), 500


@subscriptions_bp.route('/subscriptions/<int:subscription_id>/status', methods=['PUT'])
def toggle_subscription_status(subscription_id):
    """切换订阅状态"""
    try:
        subscription = Subscription.query.get(subscription_id)
        if not subscription:
            return jsonify({
                'success': False,
                'message': '订阅不存在'
            }), 404

        subscription.is_active = not subscription.is_active
        db.session.commit()

        return jsonify({
            'success': True,
            'data': subscription.to_dict(),
            'message': f'订阅已{"开启" if subscription.is_active else "关闭"}'
        })

    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': str(e)
        }), 500


@subscriptions_bp.route('/subscriptions/<int:subscription_id>/auto_download', methods=['PUT'])
def toggle_auto_download(subscription_id):
    """切换自动下载状态"""
    try:
        subscription = Subscription.query.get(subscription_id)
        if not subscription:
            return jsonify({
                'success': False,
                'message': '订阅不存在'
            }), 404

        subscription.auto_download = not subscription.auto_download
        db.session.commit()

        return jsonify({
            'success': True,
            'data': subscription.to_dict(),
            'message': f'自动下载已{"开启" if subscription.auto_download else "关闭"}'
        })

    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': str(e)
        }), 500


@subscriptions_bp.route('/subscriptions/<int:subscription_id>/crawl', methods=['POST'])
def manual_crawl(subscription_id):
    """手动爬取"""
    try:
        subscription = Subscription.query.get(subscription_id)
        if not subscription:
            return jsonify({
                'success': False,
                'message': '订阅不存在'
            }), 404

        # 这里调用爬取函数（后续实现）
        from src.services.crawler import crawl_subscription
        result = crawl_subscription(subscription)

        if result['success']:
            return jsonify({
                'success': True,
                'message': '爬取任务已启动',
                'data': result.get('data', {})
            })
        else:
            return jsonify({
                'success': False,
                'message': result.get('message', '爬取失败')
            }), 500

    except Exception as e:
        return jsonify({
            'success': False,
            'message': str(e)
        }), 500

